gameUtilID = 'gameUtilOther';

var focusEditorRetries;
var MAX_FOCUS_EDITOR_RETRIES = 10;
var FOCUS_EDITOR_RETRY_INTERVAL = 100;	// msec


function SFLoad()
{
	gameUtilJS = document.getElementById(gameUtilID);
	gameContentJS = document.getElementById(gameContentID);
	
	gameUtilJS.style.visibility = "hidden";
	gameUtilJS.contentWindow.document.body.innerHTML = "a";
	gameUtilJS.contentWindow.document.designMode = "on";
	/*gameUtilJS.contentWindow.addEventListener('keydown', SFKeyDownHandler, false);
	gameUtilJS.contentWindow.addEventListener('keypress', SFKeyPressHandler, false);
	gameUtilJS.contentWindow.addEventListener('keyup', SFKeyUpHandler, false);

	window.onmousewheel = document.onmousewheel = SFWheel;
	window.mousedown = document.onmousedown = SFOnRightClick;
	window.addEventListener("mousedown", SFOnRightClick, true);*/
}

function SFChangeGameSize(width, height)
{
	gameContentJS.setAttribute("width", width);
	gameContentJS.setAttribute("height", height);
	window.resizeBy(width - prevWidth, height - prevHeight );
	prevWidth = width;
	prevHeight = height;
}

function SFStopEvent(oEvent)
{
	oEvent.preventDefault();
	oEvent.stopPropagation();
}

var safariKeys = {
       25 :  9,	// shift-tab
    63234 : 37, // left
    63235 : 39, // right
    63232 : 38, // up
    63233 : 40, // down
    63276 : 33, // page up
    63277 : 34, // page down
    63272 : 46, // delete
    63273 : 36, // home
    63275 : 35  // end
};

var ctrlableKeys = {
	 8 : 1,		// delete
	 9 : 1,		// tab
	13 : 1,		// return

	33 : 1,		// page up
	34 : 1,		// page down
	35 : 1,		// end
	36 : 1,		// home

	37 : 1,		// left
	38 : 1,		// up
	39 : 1,		// right
	40 : 1		// down
};

function SFIsControlKey(oEvent)
{
	var sChar = String.fromCharCode(oEvent.keyCode).toLowerCase();
	var ctrlKey;
	if (sChar == 'b' || sChar == 'u' || sChar == 'i' || safariKeys[oEvent.keyCode] != null || ctrlableKeys[oEvent.keyCode] != null) 
		ctrlKey = oEvent.ctrlKey;
	else
		ctrlKey = oEvent.metaKey;
	return ctrlKey;
}

function SFTypeKey(oEvent)
{
	// If we get one of the bizarre Safari key codes, e.g. for arrow keys, set char code to zero so
	// that we look like more 'normal' browsers, e.g. Firefox.
	var charCode = oEvent.charCode;
	var keyCode = safariKeys[oEvent.keyCode];

	if (keyCode)
		charCode = 0;
	else
		keyCode = oEvent.keyCode;

	// If we see a bizarre Safari character code, clear it. The 'normal' value is in keyCode.
	var sfCharCode = safariKeys[oEvent.charCode];
	if (sfCharCode)
		charCode = 0;

	gameContentJS.onKeyPressMZ(charCode, keyCode, SFIsControlKey(oEvent), oEvent.metaKey, oEvent.shiftKey);
}

// a variable that keeps track of whether we are expecting a dead key
// to arrive.
var deadKeyWalking = false;

function SFKeyDownHandler(oEvent)
{
//	doTrace("keydown: charCode=" + oEvent.charCode + " keyCode=" + oEvent.keyCode + " meta="+oEvent.metaKey + " ctrl="+oEvent.ctrlKey + " shift="+oEvent.shiftKey);
	
	var sChar = String.fromCharCode(oEvent.keyCode).toLowerCase();
    if (oEvent.keyCode == 229)
    {
        if (!deadKeyWalking)
            gameUtilJS.contentWindow.document.body.innerHTML = 'q';
        deadKeyWalking = true;
        return;
    }
	if (oEvent.metaKey)
	{
		if (sChar == 'a')
		{
			SFSelect();
			SFStopEvent(oEvent);
			SFTypeKey(oEvent);
		}
		else if (sChar == 'c')
		{
			gameUtilJS.contentWindow.document.body.innerHTML = gameContentJS.onBrowserCopy();
			SFSelect();
		}
		else if (sChar == 'v')
		{
			SFSelect();
		}
		else if (sChar == 'x')
		{
			gameUtilJS.contentWindow.document.body.innerHTML = gameContentJS.onBrowserCut();
			SFSelect();
			setTimeout('SFRestoreMinimumText()', 0);
		}
		else if (sChar == 'q' || sChar == 'w' || sChar == 'r' || sChar == 'n' || sChar == 't')	// quit, close-window, reload, new-window, new-tab
		{
			// let's let Safari have these
		}
		else
		{
			SFStopEvent(oEvent);
			SFTypeKey(oEvent);
		}
	}
	else if ((SFIsControlKey(oEvent) && oEvent.keyCode != 13 && !SFIsControlTab(oEvent)) || SFIsNavigationKeyDown(oEvent) || SFIsDeleteKeyDown(oEvent))
	{
		SFTypeKey(oEvent);
	}
}

function SFOnRightClick(oevent)
{
	if (oevent.button != 0) 
    {
		SFKillEvents(oevent);
		if(oevent.target.id == appName) 
		{
    		gameContentJS.openRightClick();
		}
	}
}

function SFKillEvents (eventObject) 
{
	if(eventObject) 
	{
		if (eventObject.stopPropagation) eventObject.stopPropagation();
		if (eventObject.preventDefault) eventObject.preventDefault();
		if (eventObject.preventCapture) eventObject.preventCapture();
	   	if (eventObject.preventBubble) eventObject.preventBubble();
	}
}

// Tells whether key down event is a navigation one
function SFIsNavigationKeyDown(oEvent)
{
	var result = false;
	if ((oEvent.keyCode >= 33 && oEvent.keyCode <= 40) ||
	    (oEvent.keyCode >= 63232 && oEvent.keyCode <= 63235))
		result = true;
//	doTrace("SFIsNavigationKeyDown: returning " + result);
	return result;
}

// Tells whether key press event is a navigation one
function SFIsNavigationKeyPress(oEvent)
{
	var result = false;
	if (oEvent.keyCode >= 63232 && oEvent.keyCode <= 63235)
		result = true;
//	doTrace("SFIsNavigationKeyPress: returning " + result);
	return result;
}

// Tells whether key down event is backspace or delete
function SFIsDeleteKeyDown(oEvent)
{
	return oEvent.keyCode == 8 || oEvent.keyCode == 46;
}

// Tells whether key press event is backspace or delete
function SFIsDeleteKeyPress(oEvent)
{
	return oEvent.keyCode == 8 || safariKeys[oEvent.keyCode] == 46;
}

// Tells whether key event is control-tab
function SFIsControlTab(oEvent)
{
	return oEvent.keyCode == 9 && oEvent.ctrlKey;
}

function SFKeyPressHandler(oEvent)
{
    deadKeyWalking = false; // if we got a key press, then any pending dead key will be handled here
//	doTrace("keypress: charCode=" + oEvent.charCode + " keyCode=" + oEvent.keyCode + " meta="+oEvent.metaKey + " ctrl="+oEvent.ctrlKey + " shift="+oEvent.shiftKey);
	var sChar = String.fromCharCode(oEvent.keyCode).toLowerCase();
	if (oEvent.metaKey)
	{
		if (sChar == 'v')
		{
			setTimeout('SFOnAfterPaste()', 0);
		}
	}
	if (!oEvent.metaKey && !SFIsNavigationKeyPress(oEvent) && !SFIsDeleteKeyPress(oEvent) && !SFIsControlTab(oEvent))
	{
		SFTypeKey(oEvent);
		SFRestoreMinimumText();
	}
	// For shift-arrow selection, we have to prevent the key from being
	// processed by Safari, because it could end up selecting the iframe
	// itself instead of its contents.
	if (oEvent.shiftKey && SFIsNavigationKey(oEvent))
	{
		SFSelect();
		SFStopEvent(oEvent);
	}
	if (oEvent.keyCode == 8 || oEvent.keyCode == 25)
		SFStopEvent(oEvent);
	if (oEvent.keyCode == 9 && oEvent.ctrlKey == false)
		SFStopEvent(oEvent);
}

function SFKeyUpHandler(oEvent)
{
//	doTrace("keyup: charCode=" + oEvent.charCode + " keyCode=" + oEvent.keyCode + " meta="+oEvent.metaKey + " ctrl="+oEvent.ctrlKey + " shift="+oEvent.shiftKey);
//	doTrace('innerHTML=|'+gameUtilJS.contentWindow.document.body.innerHTML + '|');
	if (oEvent.keyCode == 8)
		SFStopEvent(oEvent);
	else if (SFIsControlTab(oEvent))
		SFTypeKey(oEvent);
	try {
        if (deadKeyWalking)
        {
            var sel = gameUtilJS.contentWindow.getSelection();
            var tc = sel.getRangeAt(0).endContainer.textContent + "@";
            var myCharCode = tc.charCodeAt(0);
            if (myCharCode >= 192 && myCharCode <= 255)
            {
                gameContentJS.onKeyPressMZ(myCharCode, oEvent.keyCode, oEvent.ctrlKey, oEvent.metaKey, oEvent.shiftKey);
                deadKeyWalking = false;
                return;
            }
        }

		gameContentJS.onKeyUpMZ(oEvent.charCode, oEvent.keyCode, oEvent.ctrlKey, oEvent.altKey, oEvent.shiftKey);
	} catch (e) {
		alert(e.name);
	}
}

function SFRestoreMinimumText()
{
	if (gameUtilJS.contentWindow.document.body.innerHTML == '' || gameUtilJS.contentWindow.document.body.innerHTML.length > 10)
	{
//		doTrace("SFRestoreMinimumText: resetting");
		gameUtilJS.contentWindow.document.body.innerHTML = minimumText;
		SFUnselect();
	}
	else
	{
//		doTrace("SFRestoreMinimumText: no action");
	}
}

function SFReturnFocusToEditor()
{
	focusEditorRetries = 0;
	SFReturnFocusToEditorRetry();
}

function SFReturnFocusToEditorRetry()
{
	gameUtilJS.contentWindow.focus();
	if (focusEditorRetries < MAX_FOCUS_EDITOR_RETRIES)
		setTimeout(SFReturnFocusToEditorRetry, (focusEditorRetries++)*FOCUS_EDITOR_RETRY_INTERVAL);
}

function SFReturnFocusToCMM()
{
	setTimeout('document.getElementById(appName).focus();', 0);
}

function SFWheel(event)
{
//	doTrace('SFWheel');
     var delta = 0;
     if (event.wheelDelta)             // IE case
          delta = event.wheelDelta;
    delta = delta / 36;
//    doTrace('delta='+delta);
     if (delta)
     {
          gameContentJS.onMouseWheel(delta);
     }
}

// design mode gameUtilJS has focus
function SFFocusHandler()
{
	gameContentJS.haveWindowFocus(true);
}

// design mode gameUtilJS has lost focus
function SFBlurHandler()
{
	gameContentJS.haveWindowFocus(false);
}

function doTrace(msg)
{
	if (trace != null)
	{
		trace.contentWindow.document.body.innerHTML = trace.contentWindow.document.body.innerHTML + msg + '<br>';
	}
}